perm filename JUST[E,ALS]3 blob
sn#219263 filedate 1976-06-17 generic text, type C, neo UTF8
COMMENT ⊗ VALID 00005 PAGES
C REC PAGE DESCRIPTION
C00001 00001
C00002 00002 MINTXT TABCNT TABTAB JPARAM JGINIT JGB JGIND JGMAR JGET TJGET
C00019 00003 JCTAB
C00033 00004 JSET JUST
C00045 00005 INDENT INDMAR CENTER
C00050 ENDMK
C⊗;
;MINTXT TABCNT TABTAB JPARAM JGINIT JGB JGIND JGMAR JGET TJGET
MINTXT←←3 ;Minimum allowed text length or TAB field
TJSCNT←←2 ;Minimum number of spaces to terminate a TAB field
TABCNT←←50 ;Allow 40 tabs
IMPURE
PMARO: 0
LMARO: 0
JPMARO: 0
JLMARO: 0
JPMAR: 0
JLMAR: 0
JRMAR: 69
JBNUM: 1
JBNUMO: 1
TPMARO: 0
TLMARO: 0
TPMAR: 0
TLMAR: 0
TRMAR: 69
TBNUM: 1
TBNOMO: 1
TABTAB: BLOCK TABCNT
PURE
; Subroutine to read typed-in decimal numbers.
;Returns the number in A, the terminating character in C and
;a count of the number of digits in B.
JPARAM: SETZB A,B
SETZ C,
JPAR0: PUSHJ P,TYI ;Get first character if any
POPJ P,
CAIN C," "
JRST JPAR0 ;Extra space allowed here
AOS (P) ;Skip return if something typed
JRST JPAR2
JPAR1: PUSHJ P,TYI ;Get next character
POPJ P, ;End of typing
JPAR2: CAIG C,71
CAIGE C,60
POPJ P, ;Non numeric character
IMULI A,12
ADDI A,-"0"(C)
AOJA B,JPAR1 ;B used to indicate some number (may be zero)
; Subroutine called by JGET and TJGET
;to clear PAR table and to read and store typed-in MAR values.
JGINIT: TRNN F,ARG
HRRZI A,-1 ;Use rest of page (or buffer) if no argument
MOVMM A,JCNT
JUMPE A,JGIN1 ;No text referencing
MOVE T,EXTPNT ;To read JPARAM changing instructions.
MOVEM T,TYIPNT ;Set pointer.
HRLI C,(<MOVEI C,>)
MOVEM C,TYIINS
MOVSI Q,-4
SKIPN JCNT
JRST JGIN1 ;Leave old values if JCNT=0 and no typed value
SETOM JPMAR(Q)
AOBJN Q,.-1
TRNE F,ATTMOD ;Are we in ATTACH mode?
SKIPA E,[JATAB] ; Yes so put [JATAB] in E.
MOVEI E,JPTAB ; No so put [JPTAB] in E.
MOVE D,@JPT1(E) ;Put contents of @ATTBUF or @ARRLIN in D.
HRRZM D,JPTR# ;Location of first line to examine
MOVE A,JLPTR(E) ;Number of lines
TRNE F,ATTMOD
JRST JGIN0
SUB A,ARRL
ADDI A,1
JGIN0: CAMGE A,JCNT
MOVEM A,JCNT ;Limit number of lines to the available ones
MOVN G,JCNT
HRLZS G
MOVEM G,GSAVE# ;May be needed again later
MOVSI Q,-4
PUSHJ P,JPARAM ;Read first parameter
POPJ P, ;Nothing typed
CAME C,"|" ;Was a "|" separater used, meanind JPMARO (old)
JRST JGIN2 ;No
MOVEM A,JPMARO
JGIN1: PUSHJ P,JPARAM ;Read a parameter
POPJ P, ;Nothing typed
JGIN2: JUMPE B,JGIN3 ;B=0 means no number before symbol
MOVEM A,JPMAR(Q)
SOS Q ;Q-right left with count of unspecified fields
JGIN3: CAIN C,"," ;Any other symbol terminates JGINIT
AOBJN Q,JGIN1
POPJ P,
; Subroutine called by JGMAR
;Will locate the first non-blank line after 1 or more blank lines and
;return the number of blank lines in B (B set to 0 before entry).
;Pointer to the first line of text in D and the specification of the number
;of lines of text (as a negative number) in the left of G.
JGB0: HRRZ D,(D)
JGB: HRRZ C,TXTCNT(D)
JUMPN C,JGB1
AOJA B,JGB2 ;Count blank lines for JBNUM
JGB1: CAMLE C,Q
MOVE Q,C ;Put largest in Q for JRMAR
JUMPE B,JGB2
MOVEM B,JBNUMO ;Save it here always
SKIPGE JBNUM ;Was a JBNUM typed in?
MOVEM B,JBNUM ;No, so use this value
MOVEM G,GSAVE ;May be needed twice
MOVEM D,JPTR ;Save new starting place in text
JRST JGB1B
JGB1A: HRRZ D,(D) ;Go to end for Q determination
HRRZ C,TXTCNT(D)
CAMLE C,Q
MOVE Q,C
JGB1B: AOBJN G,JGB1B ;Are we at the end?
MOVE G,GSAVE ;Reset for first line after blanks
MOVE D,JPTR
POPJ P, ;Text found after a blank line
JGB2: AOBJN G,JGB0 ;Still looking
MOVE D,JPTR ;No text found after blank line, so reset
MOVE G,GSAVE
SETZ B, ;Blank lines without text following, do not count
MOVEM B,JBNUMO ;Save it here always
SKIPGE JBNUM ;Was a JBNUM typed in?
MOVEM B,JBNUM ;No, so use this value
PUSHJ P,JGIND ;Get first line indent
HRRZ TT,T ;Save it
JGB3: AOBJP G,JGB4
HRRZ D,(D) ;Try the next line
PUSHJ P,JGIND
CAIN TT,(T)
AOJA B,JGB3 ;Another line with the same indent
JUMPE B,JGB4 ;More than 1 line with same indent?
MOVEM G,GSAVE
MOVEM D,JPTR
POPJ P,
JGB4: MOVE G,GSAVE ;Go back to first line if B still zero
MOVE D,JPTR
POPJ P,
;To get indentation
JGIND: HRRZ T,TXTCNT(D)
MOVNS T
HRLZS T
MOVE A,D
ADD A,[440700,,LLDESC]
JGIND1: ILDB C,A
CAIN C,11 ;Is it a TAB?
JRST JGIND1 ;Ignore it
CAIN C," " ;Is it a space?
AOBJN T,JGIND1 ;Count it
POPJ P,
; Subroutine called by JGET and TJGET
;To determine margins from specified text
JGMAR: MOVN G,JCNT
HRLZS G
MOVEM G,GSAVE ;May be needed twice
SETZB B,Q ;B counts blank lines, Q gets JRMAR
MOVE D,JPTR ;Pointer to the first line of text
PUSHJ P,JGB ;Find paragraph start
PUSHJ P,JGIND ;Get its indentation
MOVEM T,INDCNT# ;May be needed for TJGET case
MOVEM A,ASAVE# ;and also pointer to first non-blank character
HRRZM T,JPMARO ;Save it always
SKIPGE JPMAR ;Was a new value typed?
HRRZM T,JPMAR ;No, so use this value
AOBJN G,JGM0 ;Trouble, not enough lines
SETZM JBNUMO ;Maybe he wants 1 paragraph
JRST JGMA
JGM0: HRRZ D,(D)
PUSHJ P,JGIND ;Get indentation of the next line
JGMA: HRRZM T,JLMARO
SKIPGE JLMAR ;Was a new value typed?
HRRZM T,JLMAR ;No, so save this value
SKIPG JRMAR ;Was a new JRMAR typed in?
MOVEM Q,JRMAR ;No, so save this value
POPJ P,
;To test margins for legality
JMTEST: MOVE A,JPMAR
CAME A,JLMAR
JRST JMTES1
SKIPLE JBNUM
JRST JMTES1
MOVEI T,1
MOVEM T,JBNUM ;Must be ≥1 in this case
OUTSTR [ASCIZ/BNUM set to 1./]
JMTES1: CAMG A,JLMAR
MOVE A,JLMAR
ADDI A,MINTXT ;Minimum text length
CAMG A,JRMAR
POPJ P,
MOVEM A,JRMAR
OUTSTR [ASCIZ/ RMAR set to /]
TYPDEC A
OUTSTR [ASCIZ/ /]
POPJ P,
;Get typed-in margins and/or values identified from the specified text.
JGET: JUMPN A,JGET2
MOVSI Q,-4
JGET1: MOVE T,PMAR(Q)
MOVEM T,JPMAR(Q)
AOBJN Q,JGET1
JGET2: PUSHJ P,JGINIT ;Initialize and get typed-in margin values
CAIN C,";" ;To avoid confusion with TJGET
OUTSTR [ASCIZ/Caution, no TAB values allowed with JGET command./]
SKIPE JCNT
PUSHJ P,JGMAR ;Get margins by examining the text
OUTSTR [ASCIZ/Margins (P,L,R,B) are /]
SKIPE JBNUMO ;Were there no blank lines in text?
JRST JGET2A
MOVE A,JPMARO
CAMN A,JPMAR ;Is PMAR being changed?
JRST JGET2A
TYPDEC A ;Report it
OUTSTR [ASCIZ/|/]
JGET2A: MOVSI G,-4
SETZM TYOPNT
SKIPA
JGET3: OUTSTR [ASCIZ/,/]
MOVE A,JPMAR(G)
MOVEM A,PMARS(G)
TYPDEC A
AOBJN G,JGET3
OUTSTR [ASCIZ/. /]
AOS (P)
POPJ P,
;Get margins and also TAB settings
TJGET: JUMPN A,TJGB
MOVSI Q,-4
TJGA: MOVE T,TPMAR(Q)
MOVEM T,JPMAR(Q)
AOBJN Q,TJGA
TJGB: PUSHJ P,JGINIT ;Initialize and get typed margin values
MOVSI Q,-TABCNT
SKIPG JCNT
JRST TJG1
SETZM TABTAB(Q) ;Set TABTAB to 0 if JCNT>0
AOBJN Q,.-1
TJG1: CAIE C,";"
CAIN C,"!"
SKIPA
JRST TJG7 ;No typed TAB values
SKIPLE JCNT
JRST TJG2
HLLZS TABTAB(Q) ;Zero indent values only
AOBJN Q,.-1
TJG2: MOVSI Q,-TABCNT
CAIN "!"
JRST TJG4A ;Next number is to be an indent not a field size
TJG3: PUSHJ P,JPARAM
JRST TJG7 ;A ; typed but no data
CAIE C,"@" ;Is this a multiple define
JRST TJG5
MOVE H,A ;Yes, so save repetition number in H
PUSHJ P,JPARAM ;and get field size
JRST TJG7 ;No data means leave rest unchanged
TJG4: SKIPE A ;A zero or missing value means leave unchanged
HRLZM A,TABTAB(Q)
AOBJP Q,TJG7A ;No more space so ignore the rest
SOJG H,TJG4
JRST TJG6 ;See if there are any more
TJG4A: PUSHJ P,JPARAM ;Get indent value
SKIPA ;Syntax error
JUMPG A,TJG4B ;An indent can not be zero
OUTSTR [ASCIZ/IMPROPER SYNTAX, a non-zero number must follow a "!" symbol/]
POPJ P,
TJG4B: HRRZM A,TABTAB(Q)
AOBJP Q,TJG7A
JRST TJG6
TJG5: JUMPE B,TJG6 ;Was a number typed?
HRLZM A,TABTAB(Q) ;Yes, so save it as a field length
TJG6: CAIN C,","
JRST TJG3
CAIN C,"!"
JRST TJG4A
SKIPA
TJG7A: OUTSTR [ASCIZ/ Too many TABs typed, will ignore rest. /]
TJG7: SKIPN JCNT ;Are values to be deduced from the text?
JRST TJG18 ;No
PUSHJ P,JGMAR ;Get margins from the text
MOVSI Q,-TABCNT
MOVE A,ASAVE ;Get back to the first non-space char in 1st line
MOVE G,INDCNT ;Get character counter for first non-space
TJG8B: SETZ T,
TJG8C: SETZ H,
TJG8: AOS T ;We start on the first char
ILDB C,A
CAIE C," "
CAIN C,11
JRST TJG11
TJG8A: AOBJN G,TJG8
JRST TJG15
;To count spaces or TABS to check field termination
TJG9A: AOS H
TJG9: AOS T
TJG10: ILDB C,A ;A space or TAB found, is there another one?
TJG11: CAIE C," " ;Is it a space?
JRST TJG12
AOBJN G,TJG9A
JRST TJG15
TJG12: CAIN C,11 ;or a TAB?
AOJA H,TJG10 ;TABs do not count in G or T, but add to H
CAIL H,TJSCNT ;Were there JSCNT or more spaces?
JRST TJG13 ;Yes, so at end of this TAB field
AOBJN G,TJG8C ;Single spaces allowed within fields
JRST TJG15
TJG13A: OUTSTR [ASCIZ/ Only /]
MOVEI A,TABCNT
TYPDEC A
OUTSTR [ASCIZ/ TABS allowed. /]
JRST TJG15
TJG13: SKIPG TABTAB(Q) ;Has this TAB been typed in?
HRLZM T,TABTAB(Q) ;Save field length
AOBJP Q,TJG13A
AOBJN G,TJG8B
TJG15: MOVSI Q,-TABCNT
MOVE TT,JPMAR
TJG16: SKIPG TABTAB(Q)
JRST TJG18 ;No more values specified
HLRZ T,TABTAB(Q)
JUMPG T,TJG17B ;A field length was specified
TJG17: HRRZ T,TABTAB(Q) ;An indent was specified
SUB T,TT
CAIL T,MINTXT
JRST TJG17A ;Field would be too small
OUTSTR [ASCIZ/ TAB field #/]
HRRZ C,Q
TYPDEC C
OUTSTR [ASCIZ/ set at min. length of /]
MOVEI T,MINTXT
TYPDEC T
OUTSTR [ASCIZ/. /]
TJG17A: HRLM T,TABTAB(Q)
TJG17B: ADD TT,T
HRRM TT,TABTAB(Q) ;May have been corrected
AOBJN Q,TJG16
JRST TJG18
TJG18: OUTSTR [ASCIZ/Margins P,L,R,B) are /]
SETZM TYOPNT
MOVSI Q,-4 ;Report values
SKIPA
TJG19: OUTSTR [ASCIZ /,/]
MOVE T,JPMAR(Q)
MOVEM T,TPMAR(Q)
TYPDEC T
AOBJN Q,TJG19
OUTSTR [ASCIZ/. /]
SKIPG TABTAB ;Are there any TABS?
JRST TJG23
OUTSTR [ASCIZ/
TAB fields /]
MOVSI Q,-TABCNT
SKIPA
TJG20: OUTSTR [ASCIZ/,/]
SETZ H,
HLRZ T,TABTAB(Q)
TJG20A: HLRZ TT,TABTAB+1(Q)
CAME T,TT
JRST TJG20B
AOS H
AOBJN Q,TJG20A
TJG20B: JUMPE H,TJG20C
AOS H ;The first one was not counted
TYPDEC H ;Count of similar fields
OUTSTR [ASCIZ/@/]
TJG20C: TYPDEC T
SKIPLE TABTAB+1(Q)
AOBJN Q,TJG20
TJG21: OUTSTR [ASCIZ/ starting at /]
MOVE T,JPMAR
ADDI T,1
TYPDEC T
MOVSI Q,-TABCNT
TJG22: OUTSTR [ASCIZ/,/]
HRRZ T,TABTAB(Q)
ADDI T,1
TYPDEC T
SKIPLE TABTAB+1(Q)
AOBJN Q,TJG22
OUTSTR [ASCIZ/. /]
AOS (P)
POPJ P,
TJG23: OUTSTR [ASCIZ/ No TABs specified./]
POPJ P,
;JCTAB
COMMENT ⊗
Register assignments used in main section of JUST (and related routines)
A Input character pointer
B Input line address
C Current character
D Output character pointer
E Address of table defining data region
F Usual flag word
G Character count for output line (-x,,0 at start)
H Special flag word
I Address of line into which characters are going
DSP Current dispatch table address
P Stack pointer, as usual
Q Temporary
T Temporary
TT Temporary
Special flag usage with F during JUST only (after initial normal usage)
NEG set to 0 for JUST, to 1 for JFILL
REL set to 0 for no par. break, to 1 for par. break
End of comment ⊗
;Special flags tested against H (for use with JUST and related commands)
JUSF←←200000 ;CR, LF, VT, FF, SP, TAB, . ! ?
; LSPC←←100000 ;Special character, previously defined
; NUMF←←40000 ;Number " "
JALL←←20000 ;Dispatch on all characters
; LETF←←10000 ;Letter (with LT2F => lower case)
; LT2F←←4000 ;Alone=> $ % . _
JPUN←←2000 ;Sentence-ending punctuation
JCLO←←1000 ;Closing parenthesis
;Dispatch displacements used in following table
; 0 CR, LF and all chars. not allowed in in-core page representation
; 1 TAB (11)
; 2 Space (40)
; 3 Sentence terminating punctuation . ? !
; 4 Closures ) ] > } "
; 5 All other normal characters
;Special character-dispatch table for use with JUST and related commands
JCTAB: JALL!JUSF,,(DSP) ;NUL 0
REPEAT 8<JALL,,5(DSP)> ;↓ α β ∧ ¬ ε π λ 1,2,3,4,5,6,7,10
JALL!JUSF!LSPC,,1(DSP) ;TAB 11
REPEAT 3,<JALL!JUSF!LSPC,,(DSP)> ;LF,VT,FF 12,13,14
JALL!JUSF!LSPC,,(DSP) ;CR 15
JALL,,5(DSP) ;∞ 16
JALL,,5(DSP) ;∂ 17
REPEAT 16,<JALL..5(DSP)> ; ⊂ ⊃ ∩ ∪ ∀ ∃ ⊗ ↔ _ → ~ ≠ ≤ ≥ ≡ ∨ 20 thru 37
JALL!JUSF,,2(DSP) ;SP 40
JALL!JUSF!JPUN,,3(DSP) ;! 41
JALL!JCLO,,4(DSP) ;" 42
REPEAT 5,<JALL,,5(DSP)> ;# % & ' 43,44,45,46,47
JALL!,,5(DSP) ;( 50
JALL!JCLO,,4(DSP) ;) 51
REPEAT 4,<JALL,,5(DSP)> ;* + , - 52,53,54,55
JALL!JUSF!JPUN,,3(DSP) ;. 56
JALL,,5(DSP) ;/ 57
REPEAT 10,<JALL!NUMF,,5(DSP)> ;0,1,2,3,4,5,6,7,8,9 60 thru 71
REPEAT 2,<JALL!JPUN,,5(DSP)> ; : ; 72,73
REPEAT 2,<JALL,,5(DSP)> ; < = 74,75
JALL!JCLO,,4(DSP) ; > 76
JALL!JUSF!JPUN,,3(DSP) ;? 77
JALL,,5(DSP) ;@ 100
REPEAT 26,<JALL!LETF,,5(DSP)> ;A to Z 101 thru 132
REPEAT 2,<JALL,,5(DSP)> ;[ \ 133,134
JALL!JCLO,,4(DSP) ;] 135
REPEAT 3,<JALL,,5(DSP)> ;↑ ← ` 136,137,140
REPEAT 26,<JALL!LETF!LT2F!,,5(DSP)> ;a th z 141 thru 172
JALL,,5(DSP) ;{ 173
JALL,,5(DSP) ;| 174
JALL!JUSF!LSPC,,(DSP) ;ALT 175
JALL!JCLO,,4(DSP) ;} 176
JALL!JUSF!NSPEC,,(DSP) ;RUBOUT 177
IMPURE
;Memory locations to hold other variables
JCNT: 0 Count of lines to be processed
JCNTC: 0 Current value of JCNT
JPTR: 0 Location of first line of text being processed
JPTRC: 0 ;Location of first line of group currently being handled
JRPT: 0 Next line after text being processed
JWCOL: 0 Char count at last word break
JSCNT: 0 Word break count
JBUGR: 0 Bugger factor to distribute extra spaces
JWPT: 0 Accumulated count of extra spaces added
JSINC: 0 Needed spaces times 8
JSIZE: 0 JSINC times number of breaks already processed
JMARG: 0 ;Current output line's left margin
PARFLG: 0 ;Set for new par. conditions as defined by PMARO, LMARO and BNUMO
; Value assigned to PARFLG
; 0 means blank line needed to signal new par.
; -1 means new par. every new line
; +1 means new par if indent is >1
; X>1 means new par. if indent is =X
PURE
; Routine for setting up correct value for PARFLG
PARSET: SETZM PARFLG ;Used if blank line needed to signal new par.
MOVE T,PMARO
CAME T,LMARO
JRST PARSE2 ;Test some more
SKIPN BNUMO
SETOM PARFLG ;Every old line a new par. in this case
POPJ P,
PARSE2: AOS PARFLG ;Prepare to accept any >1 indent
SKIPE BNUMO ;if BNUMO=0
MOVEM T,PARFLG ;Requires indent=PARO if BNUMO≠0
POPJ P,
; Subroutine to get new par. indicator
P1NXTL:
PARGET: TRZ F,REL ;Means no new par.
HRRZ B,(B)
MOVE A,B
ADD A,[440700,,LLDESC]
MOVE T,TXTCNT(B)
JUMPE T,PARGE2 ;A blank line
SKIPN TT,PARFLG ;Test conditions
POPJ P, ;No par indicated
JUMPL TT,PARGE2 ;Always a new par.
MOVE T,A ;We will have to test new line indent
SETZ TT,
PARGE1: ILDB C,T
CAIN C,11
JRST PARGE1
CAIN C,40
AOJA TT,PARGE1
CAMN TT,PARFLG ;Is indent equal to PMARO
JRST PARGE2 ;Yes, so a new par.
MOVE T,PARFLG
CAIN T,1 ;Will a >1 indent suffice?
CAIG TT,1 ;Is indent greater than 1?
POPJ P, ;No
PARGE2: TRO F,REL ;New paragraph signal
POPJ P,
; For second pass when input line is exhausted
NEXTLI:
HLRZ T,TXTCNT(B)
MOVNI T,(T) ;and do 1's complement of T
ADDM T,@JCPTR(E) ;add this to # in CHARS or ATTSIZ.
SOS @JLPTR(E) ;Subtract 1 from # in LINES or ATTNUM.
HRRZ B,(B) ;Get line forward pointer
MOVEM B,JPTR ;and put it in JPTR.
MOVSI T,JPTR ;with JPTR location in left half
HLLM T,(B) ;of pointer for line pointed to.
PUSHJ P,FSGIVE ;Give up storage space.
MOVE A,B
ADD A,[440700,,LLDESC]
POPJ P,
; Action on reaching a CR in the input text
JUSTCR:
SKIPN JPASSF ;Is this the first pass
JRST JUSTC3 ;Yes
PUSHJ P,NEXTLI ;Finish off line and get next
SOSG JCNT
JRST JUSTC5 ;We should never get here, but just in case
JUSTC1: MOVEI C,40
SOS (P) ;To interpret the CR
POPJ P,
; First pass treatment
JUSTC3: SOSG JCNTC
JRST JUSTC4 ;Treat end of text as end of par. here
PUSHJ P,PARGET ;To get correct par info.
TRNN F,REL
JRST JUSTC1 ;No new par. so replace CR with space and continue
JUSTC4: TRO F,REL ;May enter here if end of data
CAIN DSP,J1DSP ;Save data only after a non-space last char.
JRST JUSTC5
AOS JSCNT ;Add to word break count
HRRZM G,JWCOL ;Char count at this word break
JUSTC5: AOS (P) ;Forces an exit from loop without incrementing G
POPJ P,
; To introduce extra spaces as required to justify
JUSPAD: SKIPN T,JSINC ;8 times the needed number of extra spaces
POPJ P, ;Exit if no extra spaces are required
ADDB T,JWSIZE
IDIV T,JSCNT ;Divide by available-location count
ADD T,JBUGR ;Current bugger factor to distribute extra spaces
LSH T,-3 ;Divide by 8
SUB T,JWPT ;JWPT counts additions to date
ADDM T,JWPT
JUMPE T,JUSPA2
JUSPA1: IDPB C,D ;Add an extra space
AOBJP G,JUSPA2 ;Should always be negative
SOJG T,JUSPA1
JUSPA2: POPJ P,
; To eat all extra spaces and tabs
J1SP: MOVE C,[-3]
ADDM C,(P) ;This backs up to the ILDB command
POPJ P,
; Action at end of a word signalled by a space or tab
J2TAB: MOVEI C,40
J2SP: MOVEI DSP,J1DSP
MOVSI H,JALL
SKIPE JPASSF ;Test for pass
JRST J2SP2 ;Second pass
AOS JSCNT ;Add to word break count
HRRZM G,JWCOL ;Char count to this word break
POPJ P,
J2SP2: TRNN F,NEG!REL ;Is this line to be justified?
PUSHJ P,JUSPAD ;Introduce extra spaces as needed
POPJ P,
; Action on receipt of a sentence-terminating type punctuation mark
J2PUN: MOVEI DSP,J3DSP
MOVSI H,JALL
POPJ P,
; Action at end of sentence signalled by punctuation and space or tab
J3TAB: MOVEI C,40
J3SP: MOVEI DSP,J1DSP
SKIPE JPASSF
JRST J3SP2 ;Its on the second pass
AOS JSCNT ;Add to word break count
HRRZM G,JWCOL ;Char count at this word break
AOBJN G,J3SP1 ;Count for an extra space if possible
SUB G,[1,,1]
J3SP1: POPJ P,
J3SP2: IDPB C,D ;Introduce second space always
AOBJN G,J2SP2 ;(should always be OK)
POPJ P, ;Safety exit
; Action on normal character if using JIDSP or J3DSP
JCHAR: MOVEI DSP,J2DSP
MOVSI H,JUSTF
POPJ P,
;Special dispatch tables used with JCTAB (Table address in DSP)
; and using the above routines
; After a space with JALL flag used
J1DSP: PUSHJ P,JUSTCR ;CR
PUSHJ P,J1SP ;TAB (eaten)
PUSHJ P,J1SP ;Space (eaten)
PUSHJ P,JCHAR ;Punctuation (MOVEI DSP,J2DSP↔MOVSI H,JUSTF)
PUSHJ P,JCHAR ;Closure " "
PUSHJ P,JCHAR ;Other character " "
; After a normal char. with JUSTF flag used
J2DSP: PUSHJ P,JUSTCR ;CR
PUSHJ P,J2TAB ;TAB (MOVEI DSP,J1DSP↔MOVSI H,JALL)
PUSHJ P,J2SP ;Space " "
PUSHJ P,J2PUN ;Punctuation (MOVEI DSP,J3DSP↔MOVSI H,JALL)
JFCL ;(Never used)
JFCL ;(Never used)
; After sentence-terminating puncuation with JALL flag used
J3DSP: PUSHJ P,JUSTCR ;CR
PUSHJ P,J3TAB ;TAB (Replaced by space and handled as such)
PUSHJ P,J3SP ;Space (Introduces extra space and MOVEI DSP,J1DSP)
JFCL ;Punctuation
JFCL ;Closure
PUSHJ P,JCHAR ;Other character (MOVEI DSP,J2DSP↔MOVSI H,JUSTF)
;JSET JUST
; Get space for first new line
JNEW: PUSHJ P,ENDSET ;So new lines will be at the end of FS
TLO F,NOCHK ;Don't CORE DOWN untill through
HRRZ Q,(B)
MOVEM Q,JRPT# ;Keep current next line address
CAMN B,PAGE
TRO F,UPDTXT ;This is the first line on the page
HLLZ Q,TXTFLG(B) ;Save flags
HRRZ I,FSEND
ADDI I,1
MOVEM I,JLPT
HLLZ TT,(B) ;Use the left half of old link for
LEG MOVEM TT,(I) ;left half of the new link word, zero right
HLRZ T,TT
HRRM I,(T) ;Fix earlier forward link to the new line
LEG HLLM Q,TXTFLG(I) ;Use old flags
TLNI Q,ARRBIT ;May need to reset ARRLIN
MOVEM I,ARRLIN
TLNE Q,WINBIT ;and also WINLIN
MOVEM I,WINLIN
SETZ Q,
POPJ P,
; Get space for next output line
JMORE: HRRZ TT,FSEND ;So get space starting address
ADDI TT,1
HRRM TT,I
LEG HRLM I,(TT)
MOVEM TT,JLPT
MOVE I,JLPT
POPJ P,
;Introduce CRLF and finish off the line
JUFIX: MOVEI C,15
LEG IDPB C,D ;The CR
MOVEI C,12
LEG IDPB C,D ;And a LF
TDZA C,C
LEG IDPB C,D ;And a null
TLNE D,760000
JRST .-2
ADDI TT,2(G) ;2 for CRLF + char. count
HRLZS TT ;goes into left half
ADDI TT,(G) ;but only char. count into right half
ADDM TT,TXTCNT(I) ;Record char counts
MOVE T,JLPT ;should be same as I
;Display text must be in ASCID
ADDI T,LLDESC ;Get address of first text word
MOVEI TT,1
IORM TT,(T) ;Convert to ASCID
CAIGE T,(D)
AOJA T,.-2
MOVEI TT,2(D)
MOVSI T,TXTCOD
FSFIX TT,T
POPJ P,
; Prepare for the second pass
J2PASS: SETOM JPASSF ;Set for second pass
MOVEI DSP,J1DSP ;Always eat initial spaces
MOVSI H,JALL
AOS TT,TXTNUM
LEG HRRM TT,TXTSER(I) ;Assign I new serial number
MOVE D,I ;Set up output char pointer
ADD D,[440700,,LDESC]
MOVE T,JMARG ;Get correct current margin value
IDIVI T,10 ;See if TABs are to be used
LEG HRLZM T,TXTCNT(I) ;Start new TXTCNT (with credit for any TABs)
JUMPE T,J2PAS3 ;No TABs
MOVEI C,11
J2PAS0:
LEG IDPB C,D
MOVEI C,40
MOVEI Q,10 ;Temporary use only
ADDM Q,TXTCNT(I) ;Count as displayed chars. only
J2PAS1:
LEG IDPB C,D
SOJG Q,J2PAS1
MOVEI C,11
J2PAS2:
LEG IDPB C,D
SOJG T,J2PAS0
J2PAS3: JUMPE TT,J2PAS5 ;No extra spaces in JMARG
HRR T,TT
HRL T,TT
ADDM T,TXTCNT(I) ;Count both as stored and as displayed
MOVEI C,40
J2PAS4:
LEG IDPB C,D
SOJG TT,J2PAS4
J2PAS5: MOVE A,ASAVE
MOVE B,JPTR
MOVE C,JCNT
MOVEM C,JCNTC
POPJ P,
JFILL: TRO F,NEG ;For JFILL case
JUST: TRZ F,NEG ;For JUST case
TRNE F,ARG!ATTMOD
JRST JU1
PUSHJ P,SETARR ;JUST without an argument does entire page
MOVEI A,-1
JU1: PUSHJ P,JGINIT ;Initialize and get typed-in margins
PUSHJ P, PARSET ;Set up new par. requirements
MOVSI H,JALL ;Set to dispatch on all characters
MOVEI DSP,J1DSP ;Set dispatch for new output line
MOVE B,JPTR
TRZ F,REL ;Means not new par. on first pass
SETZM JBUGR ;Bugger factor that staggers inserted spaces
JU1A: HRRZ C,TXTCNT(B) ;Is this line blank?
JUMPN C,JU1B ;No
HRRZ B,(B) ;Skip over it
MOVEM B,JPTR ;Initial blank lines are left but signal new par
SOSG JCNT ;One less line to process
POPJ P, ;No data
TRO F,REL ;Means new par. indent to start
JRST JU1A
JUIB: PUSHJ P,JNEW ;Get space for new lines and fix flags etc.
MOVE A,B
ADD A,[440700,,LLDESC]
TRNN F,REL ;Alrready know that new par. indent is to be used
JU1C: PUSHJ P,PARGET
JU1D: MOVE G,LMAR
TRNE F,REL ;No new par indent if 0
MOVE G,PMAR
MOVEM G,JMARG ;Save as current margin for second pass
SUB G,RMAR
MOVNM G,JSIZE ;The expected size of new line less margin
SUBI G,1 ;Go 1 char. beyond on the first pass
HRLZS G
MOVEM A,ASAVE
SETZM JSCNT ;To count word separators
MOVE C,JCNT
MOVEM C,JCNTC
MOVEI DSP,J1DSP ;Always eat initial spaces
MOVSI H,JALL
;First pass
; Determine accepted-char. count, # of word separators and par. conditions
JU3: ILDB C,A
TDNE H,JCTAB(C)
XCT @JCTAB(C) ;Caution, return may be .-2, ., .+1 or .+2
AOBJN G,JU3
SKIPN JSCNT ;Have we come to a word break?
JRST JU3 ;Impossible to break line so go on
SETZM JSINC ;Safety precaution only
; Verify par. conditions
LDB C,A ;GET last char. back
CAIN C,15 ;Was it a CR?
JRST JU3B ;YES, so no further testing needed
SKIPA
JU3A: ILDB C,A
CAIE C,40
CAIN C,11
JRST JU3A ;Eat all spaces and TABs
CAIE C,15 ;Now do we find a CR?
JRST JU3B ;No, so some text is left
PUSHJ P,PARGET ;Yes, so look at next line
JU3B: TRNN F,NEG!REL ;Is this a JFILL or a last line of par.
SOSG JSCNT ;Do not count final word ending
JRST JU3A ;Line must be left un-justified
; Prepare for justification
MOVE T,JSIZE
SUB T,JWCOL
LSH T,3 ;Multiply by 8
MOVEM T,JSINC
MOVN G,JSIZE
SETZM JSIZE ;Used in the JUSPAD routine for accumulated JSINC
SETZM JWPT ;Used in JUSPAD for accumulated insertions
SKIPA
JU3D: MOVN G,JWCOL ;Un-justified case
HRLZS G
PUSHJ P,J2PASS ;Set-up fpr the second pass
; Main character transfering loop
JU4: ILDB C,A
TDNE H,JCTAB(C)
XCT @JCTAB(C) ;Caution, return may be to .-2, ., or .+1
LEG IDPB C,D
AOBJN G,JU4
PUSHJ P,JUFIX ;Fix up line just finished
MOVE T,JCNTC
MOVEM T,JCNT
SETZM JPASSF ;Get set for new first pass
TRNN F,REL ;Is it to be a new par?
JRST JU6 ;No, so go on
SKIPN Q,BNUM ;Will blank lines be needed?
JRST JU5A ;No
; Introduce needed blank lines
JU5: PUSHJ P,JMORE ;Get space for it
AOS TT,TXTNUM
LEG HRRM TT,TXTSER(I)
LEG HRRZS TXTFLG(I) ;Zero flg portion
SETZ G,
MOVE D,I
ADD D,[440700,,LLDESC]
MOVEI C,40
IDPB C,D
PUSHJ P,JUFIX ;Finish off this line
SOJG Q,JU5
; Eat any old blank lines
JU5A: PUSHJ P,NEXTLI
SOJG JCNT
JRST JU7
HRRZ T,TXTCNT(B)
JUMPE T,JU5A
PUSHJ P,JMORE ;Get space for new line
JRST JU1D
;It is safe to go on
; But, a new input line may be needed
JU6: MOVE T,A
JU6A: ILDB C,T
CAIE C,40
CAIN C,11
JRST JU6A ;Eat all spaces and TABs
CAIE C,15
JRST JU6C ;It's OK
JU6B: PUSHJ P,NEXTLI
SOSG JCNT
JRST JU7 ;WOOPS! we are through
JU6C: PUSHJ P,JMORE ;Get space for it
JRST JU1D
;Complete the links to the following text
JU7: MOVE T,JLPT ;Now fix new right link
HRRM B,(T) ;A references next line
HRLM T,(B) ;And backward link to the new line
PUSHJ P,ENDFIX
TRO F,WRITE!DSPALL
TLZ F,NOCHK
JRST JEXIT(E)
;It should be safe to FSGIVE now, count is in Q
; MOVE A,JPTR ;Get back address of first old line
; JUMPE Q,.+4
; PUSHJ P,FSGIVE ;And give up its space
; HRRZ A,(A)
; SOJG Q,.-2 ;Do this for all the old lines
;INDENT INDMAR CENTER
INDENT: TRO F,NEG ;To prevent padding
TRNN F,ATTMOD
JRST INDEN1
TRNN F,ARG
MOVEI A,-1 ;Do entire ATTACH buffer
SKIPA
INDEN1: TRO F,ARG ;Default value is 1 if not in ATTACH
PUSHJ P,INDMAR ;Initialize and get typed-in margins
MOVSI H,JALL ;Set to dispatch on all characters
MOVEI DSP,J1DSP ;Set dispatch for new output line
SETOM PARFLG ;To force a new line on each CR
MOVE B,JPTR
; To read in a single margin specification returning value in A
; 7777 means do not change. Uses A, C and T registers.
INDMAR: MOVE T,EXTPNT ;To read margin changing instructions.
MOVEM T,TYIPNT ;Set pointer.
HRLI C,(<MOVEI C,>)
MOVEM C,TYIINS
SETZ T,
MOVEI A,7777 ;This means use default value
INDMA2: PUSHJ P,TYI ;Get first character if any.
POPJ P, ;We are to use default values.
CAIN C," "
JRST INDMA2 ;Ignore an extra space in here.
CAIN C,"+"
JRST INDMA2 ;Ignore a + sign
CAIN C,"-"
SOJA T,INDMA2
SETZ A,
INDMA3: CAIG C,71
CAIGE C,60
JRST INDMA4
IMULI A,12
ADDI A,-"0"(C)
CAILE A,EDCHRL ;Allow only 126 display char. because of line buffer
MOVEI A,EDCHRL
PUSHJ P,TYI
JRST INDMA4 ;We can only have one number anyway.
JRST INDMA3
INDMA4: SKIPE T
MOVNS A
POPJ P,
LFARR:
RFARR:
JLEFT:
ALINE:
ALIGN:
CENTER: TRO F,NEG ;To prevent padding
TRNN F,ATTMOD
JRST CENT1
TRNN F,ARG
MOVEI A,-1 ;Do entire ATTACH buffer
SKIPA
CENT1: TRO F,ARG ;Default value is 1 if not in ATTACH
PUSHJ P,JGINIT ;Initialize and get typed-in margins
MOVSI H,JALL ;Set to dispatch on all characters
MOVEI DSP,J1DSP ;Set dispatch for new output line
SETOM PARFLG ;To force a new line on each CR
MOVE T,RMAR
SUB T,LMAR
MOVEM T,JSIZE ;Use for centering
MOVE B,JPTR
CENT2: HRRZ C,TXTCNT(B) ;Is this line blank?
JUMPN C,CENT3 ;No
HRRZ B,(B) ;Skip over it
MOVEM B,JPTR
SOSG JCNT ;One less line to process
JRST CENT2
POPJ P, ;No data
CENT3: PUSHJ P,JNEW ;Get space for new lines and fix flags etc.
CENT3A: MOVE A,B
ADD A,[440700,,LLDESC]
MOVSI G,-1 ;Only limit on line size
CENT4: ILDB C,A
TDNE H,JCTAB(C)
XCT @JCTAB(C)
AOBJN G,CENT4
MOVE T,JSIZE
SUB T,JWCOL
SKIPGE T
MOVEI T,0
LSH T,-1 ;Divide by 2
MOVEM T,JMARG ;Set new margin
MOVN G,JWCOL
HRLZS G
PUSHJ P,J2PASS ;This will work here
CENT5: ILDB C,A
TDNE H,JCTAB(C)
XCT @JCTAB(C)
IDPB C,D
AOBJN G,CENT5
PUSHJ P,JUFIX
CENT6: PUSHJ P,NEXTLI
SOJG JCNT
JRST CENT8
HRRZ T,TXTCNT(B)
JUMPN T,CENT7
AOS TT,TXTNUM
LEG HRRM TT,TXTSER(I)
LEG HRRZS TXTFLG(I) ;Zero flg portion
SETZ G,
MOVE D,I
ADD D,[440700,,LLDESC]
MOVEI C,40
IDPB C,D
PUSHJ P,JUFIX ;Finish off this line
JRST CENT6
CENT7: PUSHJ P,JMORE
JRST CENT3A
CENT8: JRST JU7